import { GEOMETRYTYPE } from '../const'
import { inertElement2Array } from '../utils/common'
import { Point, LineString } from 'ol/geom'
import { Fill, Circle, Stroke, Style } from 'ol/style'
import DragPan from 'ol/interaction/DragPan'
import { Select } from 'ol/interaction'
import { fromLonLat } from 'ol/proj'
import { singleClick } from 'ol/events/condition'
import Overlay from 'ol/Overlay'
import centroid from '@turf/centroid'
import VectorLayer from 'ol/layer/Vector'
import VectorSource from 'ol/source/Vector'
import Feature from 'ol/Feature'
import {
  feature2Geojson,
  geojson2Features,
  mergeFeatures,
  filterDuplicatePoints,
  getCircleCoords,
  toggleDoubleZoom,
  lineStringCut,
  polygonCut
} from '../utils/map'

let editToolThat = null
let dropButton = null
let moveButton = null
let moveState = false
let moveStart = []
let clipSource = null
let isDraw = false
let drawCoordinates = []

class EditTool {
  /**
   * 初始化构造函数
   * @param {ol.map} map - map对象
   * @param {ol.source.Vector} vectorSource - draw生成并传入
   * @param {ol.source.Layer} vectorLayer - draw生成并传入
   * @param {SnapTool} snapTool - 捕捉工具
   */
  constructor (map, vectorSource, vectorLayer, snapTool = null) {
    this._map = map

    editToolThat = this

    if (!vectorSource || !vectorLayer) {
      console.error('layer或者source参数不能为空！')
    }
    // 从draw传过来
    this._vectorSource = vectorSource
    this._vectorLayer = vectorLayer
    this._snapTool = snapTool

    // 是否开启编辑，通过select来触发切换
    this._editState = false

    // 控制节点编辑状态
    this._isEdit = false

    // 选中的feature
    this._selectFeature = null

    // 选中的coords
    this._selectCoords = []

    // 选中的marker
    this._selectMarker = null

    // 右键菜单
    this._contextmenu = null

    // 移动按钮
    this._moveButton = null

    // 初始化，select交互
    this._init()
  }

  /**
   * 切换编辑状态
   * @param {boolean} isEdit - true, 开启编辑；false, 关闭编辑
   */
  toggleEdit (isEdit) {
    editToolThat._selectInteraction.setActive(isEdit)
    if (isEdit) {
      editToolThat._map.on('pointermove', this._mapMouseMoveEvent)
    } else {
      editToolThat._map.un('pointermove', this._mapMouseMoveEvent)
      editToolThat._selectInteraction.getFeatures().clear()
      this._endEdit()
    }
  }

  /**
   * 合并要素，根据选中的第一个要素确定要素类型
   */
  mergeFeature () {
    // 隐藏捕捉点和编辑点
    editToolThat._snapTool._setPosition(null)
    editToolThat._removeEditMarkers()

    const features = editToolThat._selectInteraction.getFeatures().getArray()
    if (features.length > 1) {
      let type = features[0].getGeometry().getType()
      if (type.indexOf('LineString') !== -1) type = 'LineString'
      if (type.indexOf('Polygon') !== -1) type = 'Polygon'
      const _features = features.filter(f => {
        return f.getGeometry().getType().indexOf(type) !== -1
      })
      if (_features.length < 2) {
        alert('请先选择至少两个以上相同类型的要素进行合并操作')
        editToolThat._selectInteraction.getFeatures().clear()
      } else {
        // 1.合并features
        const feature = mergeFeatures(_features)
        // 2.删除原有features
        _features.forEach(feat => {
          editToolThat._vectorSource.removeFeature(feat)
        })
        // 3.展示合并后的feature
        editToolThat._vectorSource.addFeature(feature)
      }
    }
  }

  /**
   * 裁剪feature
   */
  clipFeature () {
    if (this._selectFeature) {
      isDraw = true
      drawCoordinates = []
      clipSource.clear()

      // 禁用选中交互，移除编辑点
      editToolThat._selectInteraction.setActive(false)
      editToolThat._removeEditMarkers()

      // 绑定map事件，在地图上绘制线
      this._map.on('click', this._clickEvent)
      this._map.on('pointermove', this._pointerMoveEvent)
      this._map.on('dblclick', this._dblClickEvt)
    } else {
      alert('请先选择一个需要操作的要素！')
    }
  }

  // 结束绘制，切割并展示切割结果
  _dblClickEvt () {
    if (drawCoordinates.length === 0) return
    isDraw = false
    editToolThat._map.getTargetElement().style.cursor = 'default'
    editToolThat._selectInteraction.setActive(true)
    // 解绑map事件
    editToolThat._map.un('dblclick', editToolThat._dblClickEvt)
    editToolThat._map.un('click', editToolThat._clickEvent)
    editToolThat._map.un('pointermove', editToolThat._clickEvent)
    // 切割图形并展示
    editToolThat._clipFeature()
    clipSource.clear()

    setTimeout(() => {
      editToolThat._snapTool._setPosition(null)
      editToolThat._selectFeature = null
      drawCoordinates = []
      toggleDoubleZoom(editToolThat._map)
      editToolThat._endEdit()
    }, 500)
  }

  _clipFeature () {
    const clipedFeature = editToolThat._selectFeature
    const clipLineFeature = clipSource.getFeatures()[0]
    const clipedJson = feature2Geojson(clipedFeature)
    const clipLineJson = feature2Geojson(clipLineFeature)
    editToolThat._vectorSource.removeFeature(clipedFeature)
    const geomType = clipedJson.geometry.type
    const geojson = geomType.indexOf('LineString') !== -1 ? lineStringCut(clipedJson, clipLineJson) : polygonCut(clipedJson, clipLineJson)
    editToolThat._vectorSource.addFeatures(geojson2Features(geojson))
  }

  // map click事件
  _clickEvent (e) {
    if (!isDraw) return
    toggleDoubleZoom(editToolThat._map, false)
    // 获取捕捉点
    let coordinate = e.coordinate
    const snapCoordinate = editToolThat._snapTool ? editToolThat._snapTool.getSnapPoint(coordinate) : []
    coordinate = snapCoordinate.length === 0 ? coordinate : fromLonLat(snapCoordinate)
    drawCoordinates.push(coordinate)

    if (drawCoordinates.length > 1) {
      editToolThat._addLine2Map(drawCoordinates)
    }
  }

  // map 鼠标移动事件
  _pointerMoveEvent (e) {
    if (isDraw) {
      let coords = drawCoordinates.concat([])
      // 获取捕捉点
      let coordinate = e.coordinate
      const snapCoordinate = editToolThat._snapTool ? editToolThat._snapTool.getSnapPoint(coordinate) : []
      coordinate = snapCoordinate.length === 0 ? coordinate : fromLonLat(snapCoordinate)
      coords.push(coordinate)

      if (coords.length > 1) {
        editToolThat._addLine2Map(coords)
      }
    }
  }

  _addLine2Map (coordinates) {
    coordinates = filterDuplicatePoints(coordinates)
    clipSource.clear()
    const feature = new Feature({
      geometry: new LineString(coordinates)
    })
    clipSource.addFeature(feature)
  }

  /**
   * 初始化方法，完成select的创建
   * @private
   */
  _init () {
    editToolThat._selectInteraction = new Select({
      condition: singleClick,
      style: this._styleFunction,
      layers: [this._vectorLayer]
    })
    editToolThat._map.addInteraction(editToolThat._selectInteraction)
    editToolThat._selectInteraction.setActive(false)
    editToolThat._selectInteraction.on('select', function (e) {
      if (!editToolThat._selectInteraction.getActive()) return
      editToolThat._endEdit()
      editToolThat._snapTool._setPosition(null)
      let features = e.target.getFeatures().getArray()
      features = features.filter(f => f.get('id'))
      let feature = features[0]
      if (feature) {
        editToolThat._editState = true
        editToolThat._selectFeature = feature
        editToolThat._updateMarkers()
      }
    })

    // 切割图层
    clipSource = new VectorSource({
      features: []
    })
    let clipLayer = new VectorLayer({
      source: clipSource,
      style: new Style({
        stroke: new Stroke({
          color: '#2600ff',
          width: 2,
          lineDash: [5, 3]
        })
      })
    })
    editToolThat._map.addLayer(clipLayer)

    // 添加移动overlay
    const moveDom = document.createElement('div')
    moveDom.classList.add('feature-move')
    editToolThat._moveButton = new Overlay({
      id: 'feature-move',
      stopEvent: true,
      offset: [0, 0],
      positioning: 'center-center',
      element: moveDom
    })
    editToolThat._map.addOverlay(editToolThat._moveButton)
    editToolThat._moveButton.setPosition(null)

    moveDom.onmousedown = function (e) {
      moveState = true
      const feature = editToolThat._selectFeature
      moveStart = feature.get('geometryType') === 'circle'
        ? feature.get('centerOrigin')
        : editToolThat._map.getEventCoordinate(e)

      editToolThat._removeEditMarkers()
    }
    moveDom.onmousemove = function (e) {
      if (moveState) {
        const movePosition = editToolThat._map.getEventCoordinate(e)
        editToolThat._moveButton.setPosition(movePosition)
        const deletX = movePosition[0] - moveStart[0]
        const deletY = movePosition[1] - moveStart[1]
        editToolThat._moveFeature(deletX, deletY)
      }
    }
    moveDom.onmouseup = function (e) {
      moveState = false
      editToolThat._updateMarkers()
    }

    // 添加编辑右键菜单
    const contextmenuDom = document.createElement('ul')
    dropButton = document.createElement('li')
    dropButton.innerText = '删除'

    moveButton = document.createElement('li')
    moveButton.innerText = '移动'

    contextmenuDom.appendChild(moveButton)
    contextmenuDom.appendChild(dropButton)

    editToolThat._contextmenu = new Overlay({
      id: 'contextmenu',
      stopEvent: true,
      offset: [0, 0],
      positioning: 'left-center',
      element: contextmenuDom,
      className: 'contextmenu'
    })
    editToolThat._map.addOverlay(editToolThat._contextmenu)
    editToolThat._contextmenu.setPosition(null)
    // 添加map dom的右键事件
    const mapContainer = editToolThat._map.getTargetElement()
    mapContainer.oncontextmenu = e => {
      e.preventDefault()// 屏蔽自带的右键事件
      if (editToolThat._selectFeature) {
        const geomType = editToolThat._selectFeature.getGeometry().getType()
        moveButton.style.display = geomType === 'Point' ? 'none' : 'block'
        const position = editToolThat._map.getEventCoordinate(e)
        editToolThat._contextmenu.setPosition(position)
      }
    }
    // 添加删除事件
    dropButton.onclick = e => {
      if (confirm('确认删除该图形吗？')) {
        const feature = editToolThat._selectFeature
        editToolThat._endEdit()
        editToolThat._vectorSource.removeFeature(feature)
      }
      editToolThat._contextmenu.setPosition(null)
    }
    // 添加移动事件
    moveButton.onclick = e => {
      editToolThat._contextmenu.setPosition(null)
      const feature = editToolThat._selectFeature
      const json = feature2Geojson(feature)
      const center = centroid(json)
      const position = fromLonLat(center.geometry.coordinates)
      editToolThat._moveButton.setPosition(position)
    }
  }

  /**
   * 移动要素
   * @param deletX
   * @param deletY
   * @private
   */
  _moveFeature (deletX = 0, deletY = 0) {
    const feature = editToolThat._selectFeature
    const geom = feature.getGeometry()
    const geomType = geom.getType()
    const type = feature.get('geometryType')
    let coords = editToolThat._selectCoords
    switch (type) {
      case GEOMETRYTYPE.CIRCLE: {
        const [x, y] = feature.get('centerOrigin')
        const [px, py] = feature.get('pointOrigin')
        const pt = [px + deletX, py + deletY]
        const center = [x + deletX, y + deletY]
        const r = Math.sqrt((pt[0] - center[0]) ** 2 + (pt[1] - center[1]) ** 2)
        geom.setCoordinates([getCircleCoords(center, r)])
        feature.set('point', pt)
        feature.set('center', center)
        break
      }
      case GEOMETRYTYPE.RECTANGLE:
      case GEOMETRYTYPE.POLYGON: {
        if (geomType === 'Polygon') {
          coords = coords.map(_coords => {
            return _coords.map(coord => {
              return [coord[0] + deletX, coord[1] + deletY]
            })
          })
        } else {
          coords = coords.map(_coords => {
            return _coords.map(__coords => {
              return __coords.map(coord => {
                return [coord[0] + deletX, coord[1] + deletY]
              })
            })
          })
        }
        geom.setCoordinates(coords)
        break
      }
      case GEOMETRYTYPE.LINESTRING: {
        if (geomType === 'LineString') {
          coords = coords.map(coord => {
            return [coord[0] + deletX, coord[1] + deletY]
          })
        } else {
          coords = coords.map(_coords => {
            return _coords.map(coord => {
              return [coord[0] + deletX, coord[1] + deletY]
            })
          })
        }
        geom.setCoordinates(coords)
        break
      }
    }
  }

  /**
   * 鼠标移动事件
   * @param e
   * @private
   */
  _mapMouseMoveEvent (e) {
    let cursor = ''
    if (editToolThat._map.hasFeatureAtPixel(e.pixel)) {
      const features = editToolThat._map.getFeaturesAtPixel(e.pixel)
      const feature = features[0]
      if (feature.get('geometryType')) cursor = 'pointer'
    }
    editToolThat._map.getTargetElement().style.cursor = cursor
  }

  /**
   * 添加控制点
   * @param coord
   * @param featureId
   * @param index
   * @private
   */
  _addCtrlMarker (coord, featureId, index = 0, isCenter) {
    const editMarker = document.createElement('div')
    editMarker.classList.add('edit-marker')
    if (isCenter) editMarker.classList.add('center')
    editMarker.setAttribute('feature', featureId)
    editMarker.setAttribute('index', index)
    const overlay = new Overlay({
      id: `edit-marker-${featureId}-${index}`,
      element: editMarker,
      positioning: 'center-center',
      stopEvent: true,
      offset: [0, 0]
    })
    editToolThat._map.addOverlay(overlay)
    overlay.setPosition(coord)
    // 添加拖拽事件
    editMarker.onmousedown = function (e) {
      editToolThat._toggleDragMap(false)
      editToolThat._isEdit = true
      editToolThat._moveButton.setPosition(null)
      const target = e.target
      const featureId = target.getAttribute('feature')
      const index = target.getAttribute('index')
      editToolThat._selectMarker = editToolThat._map.getOverlayById(`edit-marker-${featureId}-${index}`)
    }

    window.onmousemove = editToolThat._editMarkerMove

    window.onmouseup = function (e) {
      if (editToolThat._isEdit) {
        editToolThat._updateMarkers()
        editToolThat._selectCoords = editToolThat._selectFeature.getGeometry().getCoordinates()
        editToolThat._toggleDragMap()
        editToolThat._isEdit = false
        editToolThat._selectMarker = null
      }
    }
  }

  /**
   * 更新编辑控制点
   * @private
   */
  _updateMarkers () {
    const feature = this._selectFeature
    const featureId = feature.get('id')
    // 先删除
    editToolThat._removeEditMarkers()

    const geom = feature.getGeometry()
    const type = feature.get('geometryType')
    let coords = geom.getCoordinates()
    editToolThat._selectCoords = coords
    const geomType = geom.getType()
    switch (type) {
      case GEOMETRYTYPE.POINT: {
        editToolThat._addCtrlMarker(coords, featureId)
        break
      }
      case GEOMETRYTYPE.LINESTRING: {
        if (geomType === 'LineString') {
          coords.forEach((coord, index) => {
            editToolThat._addCtrlMarker(coord, featureId, index)
            if (index > 0) {
              const coordBefore = coords[index - 1]
              const center = [(coordBefore[0] + coord[0]) / 2, (coordBefore[1] + coord[1]) / 2]
              let idx = [index - 1, index].join(';')
              editToolThat._addCtrlMarker(center, featureId, idx, true)
            }
          })
        } else { // 复杂线
          coords.forEach((_coords, pindex) => {
            _coords.forEach((coord, index) => {
              editToolThat._addCtrlMarker(coord, featureId, [pindex, index].join(';'))
              if (index > 0) {
                const coordBefore = _coords[index - 1]
                const center = [(coordBefore[0] + coord[0]) / 2, (coordBefore[1] + coord[1]) / 2]
                let idx = [pindex, index - 1, index].join(';')
                editToolThat._addCtrlMarker(center, featureId, idx, true)
              }
            })
          })
        }
        break
      }
      case GEOMETRYTYPE.POLYGON: {
        if (geomType === 'Polygon') {
          coords.forEach((_coords, _index) => {
            _coords.forEach((coord, index) => {
              if (index !== _coords.length - 1) editToolThat._addCtrlMarker(coord, featureId, [_index, index].join(';'))
              if (index > 0) {
                const center = [(_coords[index - 1][0] + coord[0]) / 2, (_coords[index - 1][1] + coord[1]) / 2]
                editToolThat._addCtrlMarker(center, featureId, [_index, index - 1, index].join(';'), true)
              }
            })
          })
        } else { // 复杂多边形
          coords.forEach((_coords, _index) => {
            _coords.forEach((__coords, __index) => {
              __coords.forEach((coord, index) => {
                if (index !== __coords.length - 1) editToolThat._addCtrlMarker(coord, featureId, [_index, __index, index].join(';'))
                if (index > 0) {
                  const center = [(__coords[index - 1][0] + coord[0]) / 2, (__coords[index - 1][1] + coord[1]) / 2]
                  let idx = [_index, __index, index - 1, index].join(';')
                  editToolThat._addCtrlMarker(center, featureId, idx, true)
                }
              })
            })
          })
        }
        break
      }
      case GEOMETRYTYPE.RECTANGLE: {
        coords = coords[0]
        const coord = coords[2]
        editToolThat._addCtrlMarker(coord, featureId, 2)
        break
      }
      case GEOMETRYTYPE.CIRCLE: {
        editToolThat._addCtrlMarker(feature.get('point'), featureId, 0)
        break
      }
    }
  }

  /**
   * 控制点移动事件
   * @param e
   * @private
   */
  _editMarkerMove (e) {
    if (editToolThat._isEdit) {
      // 获取捕捉点
      const scrPt = [e.layerX, e.layerY]
      let mapPt = editToolThat._map.getCoordinateFromPixel(scrPt)
      const snapCoordinate = editToolThat._snapTool ? editToolThat._snapTool.getSnapPoint(mapPt) : []
      mapPt = snapCoordinate.length === 0 ? mapPt : fromLonLat(snapCoordinate)
      editToolThat._selectMarker.setPosition(mapPt)

      // 获取修改图形
      const target = editToolThat._selectMarker.getElement()
      const featureId = target.getAttribute('feature')
      const features = editToolThat._selectInteraction.getFeatures()
      let feature = null
      for (let i = 0; i < features.getLength(); i++) {
        const f = features.item(i)
        if (f.get('id') === featureId) {
          feature = f
          break
        }
      }
      if (!feature) return

      let index = target.getAttribute('index').split(';').map(Number)
      const isCenter = target.classList.contains('center')
      const geom = feature.getGeometry()
      const geomType = geom.getType()
      const type = feature.get('geometryType')
      let coords = editToolThat._selectCoords
      switch (type) {
        case GEOMETRYTYPE.POINT: {
          geom.setCoordinates(mapPt)
          break
        }
        case GEOMETRYTYPE.RECTANGLE: {
          coords = coords[0]
          const [x0, y0] = coords[0]
          const [x1, y1] = mapPt
          coords = [[
            coords[0],
            [x1, y0],
            mapPt,
            [x0, y1],
            coords[0]
          ]]
          geom.setCoordinates(coords)
          break
        }
        case GEOMETRYTYPE.CIRCLE: {
          const center = feature.get('center')
          const [x0, y0] = center
          const [x1, y1] = mapPt
          const dx = x0 - x1
          const dy = y0 - y1
          const r = Math.sqrt(dx ** 2 + dy ** 2)
          feature.set('point', mapPt)
          feature.set('pointOrigin', mapPt)
          geom.setCoordinates([getCircleCoords(center, r)])
          break
        }
        case GEOMETRYTYPE.LINESTRING: {
          if (geomType === 'LineString') {
            let idx = isCenter ? index[1] : index[0]
            // 将中心点插入
            if (isCenter) {
              const x = (coords[idx - 1][0] + coords[idx][0]) / 2
              const y = (coords[idx - 1][1] + coords[idx][1]) / 2
              const center = [x, y]
              coords = inertElement2Array(coords, center, idx)
            } else {
              const prevIndex = idx - 1
              const nextIndex = idx + 1
              if (prevIndex >= 0) {
                const x = (coords[idx - 1][0] + coords[idx][0]) / 2
                const y = (coords[idx - 1][1] + coords[idx][1]) / 2
                const center = [x, y]
                const centerIndex = [prevIndex, idx].join(';')
                const overlay = editToolThat._map.getOverlayById(`edit-marker-${featureId}-${centerIndex}`)
                if (overlay) overlay.setPosition(center)
              }
              if (nextIndex < coords.length) {
                const center = [(coords[nextIndex][0] + coords[idx][0]) / 2, (coords[nextIndex][1] + coords[idx][1]) / 2]
                const centerIndex = [idx, nextIndex].join(';')
                const overlay = editToolThat._map.getOverlayById(`edit-marker-${featureId}-${centerIndex}`)
                if (overlay) overlay.setPosition(center)
              }
            }
            coords[idx] = mapPt
          } else {
            // 复制坐标点
            coords = [...coords]
            let idx = isCenter ? index[2] : index[1]
            let _coords = coords[index[0]]
            // 将中心点插入
            if (isCenter) {
              const x = (_coords[idx - 1][0] + _coords[idx][0]) / 2
              const y = (_coords[idx - 1][1] + _coords[idx][1]) / 2
              const center = [x, y]
              _coords = inertElement2Array(_coords, center, idx)
              coords[index[0]] = _coords
            } else {
              const prevIndex = idx - 1
              const nextIndex = idx + 1
              if (prevIndex >= 0) {
                const x = (_coords[idx - 1][0] + _coords[idx][0]) / 2
                const y = (_coords[idx - 1][1] + _coords[idx][1]) / 2
                const center = [x, y]
                const centerIndex = [index[0], prevIndex, idx].join(';')
                const overlay = editToolThat._map.getOverlayById(`edit-marker-${featureId}-${centerIndex}`)
                if (overlay) overlay.setPosition(center)
              }
              if (nextIndex < _coords.length) {
                const center = [(_coords[nextIndex][0] + _coords[idx][0]) / 2, (_coords[nextIndex][1] + _coords[idx][1]) / 2]
                const centerIndex = [index[0], idx, nextIndex].join(';')
                const overlay = editToolThat._map.getOverlayById(`edit-marker-${featureId}-${centerIndex}`)
                if (overlay) overlay.setPosition(center)
              }
            }
            _coords[idx] = mapPt
          }
          geom.setCoordinates(coords)
          break
        }
        case GEOMETRYTYPE.POLYGON: {
          coords = coords.concat([])
          if (geomType === 'Polygon') {
            let _coords = coords[index[0]]
            const idx = isCenter ? index[2] : index[1]
            // 将中心点插入
            if (isCenter) {
              const center = [(_coords[idx - 1][0] + _coords[idx][0]) / 2, (_coords[idx - 1][1] + _coords[idx][1]) / 2]
              _coords = inertElement2Array(_coords, center, idx)
              coords[index[0]] = _coords
            } else {
              let prevIndex = idx - 1
              let nextIndex = idx + 1
              if (idx === 0) {
                prevIndex = _coords.length - 2
                const center = [(_coords[prevIndex][0] + _coords[idx][0]) / 2, (_coords[prevIndex][1] + _coords[idx][1]) / 2]
                const centerIndex = [index[0], prevIndex, prevIndex + 1].join(';')
                const overlay = editToolThat._map.getOverlayById(`edit-marker-${featureId}-${centerIndex}`)
                if (overlay) overlay.setPosition(center)
              }
              if (prevIndex >= 0) {
                const center = [(_coords[prevIndex][0] + _coords[idx][0]) / 2, (_coords[prevIndex][1] + _coords[idx][1]) / 2]
                const centerIndex = [index[0], prevIndex, idx].join(';')
                const overlay = editToolThat._map.getOverlayById(`edit-marker-${featureId}-${centerIndex}`)
                if (overlay) overlay.setPosition(center)
              }
              if (nextIndex < _coords.length) {
                const center = [(_coords[nextIndex][0] + _coords[idx][0]) / 2, (_coords[nextIndex][1] + _coords[idx][1]) / 2]
                const centerIndex = [index[0], idx, nextIndex].join(';')
                const overlay = editToolThat._map.getOverlayById(`edit-marker-${featureId}-${centerIndex}`)
                if (overlay) overlay.setPosition(center)
              }
            }
            _coords[idx] = mapPt
            if (idx === 0) _coords[_coords.length - 1] = mapPt
            coords[index[0]] = _coords
            _coords[idx] = mapPt
            if (idx === 0) _coords[_coords.length - 1] = mapPt
            geom.setCoordinates(coords)
          } else { // 复杂面处理
            const idx = isCenter ? index[3] : index[2]
            let _coords = coords[index[0]][index[1]]
            // 处理中心点
            if (isCenter) {
              const newCoords = JSON.parse(JSON.stringify(coords))
              _coords = newCoords[index[0]][index[1]]
              const center = [(_coords[idx - 1][0] + _coords[idx][0]) / 2, (_coords[idx - 1][1] + _coords[idx][1]) / 2]
              _coords = inertElement2Array(_coords, center, idx)
              newCoords[index[0]][index[1]] = _coords
              _coords[idx] = mapPt
              if (idx === 0) _coords[_coords.length - 1] = mapPt
              geom.setCoordinates(newCoords)
            } else {
              let prevIndex = idx - 1
              let nextIndex = idx + 1
              if (idx === 0) {
                prevIndex = _coords.length - 2
                const center = [(_coords[prevIndex][0] + _coords[idx][0]) / 2, (_coords[prevIndex][1] + _coords[idx][1]) / 2]
                const centerIndex = [index[0], index[1], prevIndex, prevIndex + 1].join(';')
                const overlay = editToolThat._map.getOverlayById(`edit-marker-${featureId}-${centerIndex}`)
                if (overlay) overlay.setPosition(center)
              }
              if (prevIndex >= 0) {
                const center = [(_coords[prevIndex][0] + _coords[idx][0]) / 2, (_coords[prevIndex][1] + _coords[idx][1]) / 2]
                const centerIndex = [index[0], index[1], prevIndex, idx].join(';')
                const overlay = editToolThat._map.getOverlayById(`edit-marker-${featureId}-${centerIndex}`)
                if (overlay) overlay.setPosition(center)
              }
              if (nextIndex < _coords.length) {
                const center = [(_coords[nextIndex][0] + _coords[idx][0]) / 2, (_coords[nextIndex][1] + _coords[idx][1]) / 2]
                const centerIndex = [index[0], index[1], idx, nextIndex].join(';')
                const overlay = editToolThat._map.getOverlayById(`edit-marker-${featureId}-${centerIndex}`)
                if (overlay) overlay.setPosition(center)
              }
              _coords[idx] = mapPt
              if (idx === 0) _coords[_coords.length - 1] = mapPt
              geom.setCoordinates(coords)
            }
          }
          break
        }
      }
    }
  }

  /**
   * 退出编辑
   * @private
   */
  _endEdit () {
    editToolThat._editState = false
    editToolThat._contextmenu.setPosition(null)
    editToolThat._moveButton.setPosition(null)
    editToolThat._removeEditMarkers()
    editToolThat._selectFeature = null
  }

  /**
   * 删除编辑控制点
   * @private
   */
  _removeEditMarkers () {
    const feature = this._selectFeature
    if (!feature) return
    const featureId = feature.get('id')
    let overlays = editToolThat._map.getOverlays().getArray()
    overlays = overlays.concat([])
    overlays.forEach(overlay => {
      const domId = overlay.getId()
      if (domId && domId.indexOf(`edit-marker-${featureId}`) !== -1) {
        editToolThat._map.removeOverlay(overlay)
      }
    })
  }

  /**
   * 样式函数
   * @param feat
   * @private
   */
  _styleFunction (feat) {
    let styles = []
    // 默认样式
    styles.push(new Style({
      fill: new Fill({
        color: 'rgba(0, 255, 255, 0.1)'
      }),
      stroke: new Stroke({
        color: '#00ffff',
        width: 3
      }),
      image: new Circle({
        radius: 6,
        fill: new Fill({
          color: '#00ffff'
        })
      })
    }))
    const geoType = feat.get('geometryType')
    const getCoordsPointStyle = function (coords) {
      let res = []
      coords.forEach(coord => {
        res.push(new Style({
          geometry: new Point(coord),
          image: new Circle({
            radius: 3,
            stroke: new Stroke({
              color: '#00ffff',
              width: 1
            }),
            fill: new Fill({
              color: '#ffffff'
            })
          })
        }))
      })
      return res
    }
    if (geoType !== GEOMETRYTYPE.POINT) {
      if (geoType === 'circle') {
        const point = feat.get('point')
        const center = feat.get('center')
        const line = [center, point]
        styles.push(new Style({
          geometry: new LineString(line),
          stroke: new Stroke({
            color: '#00ffff',
            width: 1
          })
        }))
        styles.push(new Style({
          geometry: new Point(point),
          image: new Circle({
            radius: 3,
            stroke: new Stroke({
              color: '#00ffff',
              width: 1
            }),
            fill: new Fill({
              color: '#ffffff'
            })
          })
        }))
        styles.push(new Style({
          geometry: new Point(center),
          image: new Circle({
            radius: 4,
            stroke: new Stroke({
              color: '#00ffff',
              width: 1
            }),
            fill: new Fill({
              color: '#ffffff'
            })
          })
        }))
      } else {
        let coords = feat.getGeometry().getCoordinates()
        if ([GEOMETRYTYPE.POLYGON, GEOMETRYTYPE.RECTANGLE].indexOf(geoType) !== -1) {
          coords = coords[0]
          coords.length = coords.length - 1
        }
        styles = [...styles, ...getCoordsPointStyle(coords)]
      }
    }
    return styles
  }

  /**
   * 切换地图拖拽事件，开启编辑时为false
   * @param state
   * @private
   */
  _toggleDragMap (state = true) {
    const dragInteraction = editToolThat._map
      .getInteractions()
      .getArray()
      .find(interaction => {
        return interaction instanceof DragPan
      })
    dragInteraction.setActive(state)
  }
}

export default EditTool
